using System.Net.Http.Json;
using Microsoft.Extensions.Logging;

namespace SumerCoreDevOps.ExecuteNodeApi.Services;

/// <summary>
/// 主节点发现服务（通过 HTTP 发现可用的主节点）
/// </summary>
public class MasterDiscoveryService
{
    private readonly ILogger<MasterDiscoveryService> _logger;
    private readonly HttpClient _httpClient;

    public MasterDiscoveryService(ILogger<MasterDiscoveryService> logger, HttpClient httpClient)
    {
        _logger = logger;
        _httpClient = httpClient;
        _httpClient.Timeout = TimeSpan.FromSeconds(10);
    }

    /// <summary>
    /// 从指定的主节点 URL 发现所有可用的主节点
    /// </summary>
    /// <param name="masterUrl">主节点 URL (例如: http://master:5000)</param>
    /// <returns>主节点端点列表</returns>
    public async Task<List<MasterEndpointInfo>> DiscoverMastersAsync(string masterUrl)
    {
        try
        {
            _logger.LogInformation("开始从 {Url} 发现主节点...", masterUrl);

            // 确保 URL 格式正确
            if (!masterUrl.StartsWith("http://") && !masterUrl.StartsWith("https://"))
            {
                masterUrl = $"http://{masterUrl}";
            }

            var discoveryUrl = $"{masterUrl.TrimEnd('/')}/api/node/discover";
            _logger.LogDebug("发送发现请求到: {Url}", discoveryUrl);

            var response = await _httpClient.GetAsync(discoveryUrl);
            response.EnsureSuccessStatusCode();

            var result = await response.Content.ReadFromJsonAsync<ApiResponse<NodeDiscoveryResponse>>();

            if (result == null || !result.Success || result.Data == null)
            {
                _logger.LogWarning("发现请求失败或返回数据为空");
                return new List<MasterEndpointInfo>();
            }

            var masters = result.Data.AvailableMasters
                .Select((m, index) => new MasterEndpointInfo
                {
                    MasterId = m.MasterId,
                    Host = m.Host,
                    TcpPort = m.TcpPort,
                    ApiPort = m.ApiPort,
                    Priority = index + 1, // 按返回顺序分配优先级
                    IsDistributed = m.IsDistributed
                })
                .ToList();

            _logger.LogInformation("发现了 {Count} 个主节点:", masters.Count);
            foreach (var master in masters)
            {
                _logger.LogInformation("  - {MasterId} ({Host}:{Port})",
                    master.MasterId, master.Host, master.TcpPort);
            }

            return masters;
        }
        catch (HttpRequestException ex)
        {
            _logger.LogError(ex, "HTTP 请求失败，无法连接到主节点: {Url}", masterUrl);
            throw new InvalidOperationException($"无法连接到主节点: {masterUrl}", ex);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "发现主节点失败: {Url}", masterUrl);
            throw;
        }
    }

    /// <summary>
    /// 尝试多个入口点发现主节点
    /// </summary>
    /// <param name="entryPoints">入口点 URL 列表</param>
    /// <returns>主节点端点列表</returns>
    public async Task<List<MasterEndpointInfo>> DiscoverFromMultipleEntryPointsAsync(List<string> entryPoints)
    {
        foreach (var entryPoint in entryPoints)
        {
            try
            {
                var masters = await DiscoverMastersAsync(entryPoint);
                if (masters.Count > 0)
                {
                    return masters;
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "从入口点 {EntryPoint} 发现失败，尝试下一个", entryPoint);
            }
        }

        throw new InvalidOperationException("所有入口点都无法发现主节点");
    }

    /// <summary>
    /// 检查主节点健康状态
    /// </summary>
    public async Task<bool> CheckHealthAsync(string masterUrl)
    {
        try
        {
            if (!masterUrl.StartsWith("http://") && !masterUrl.StartsWith("https://"))
            {
                masterUrl = $"http://{masterUrl}";
            }

            var healthUrl = $"{masterUrl.TrimEnd('/')}/api/node/health";
            var response = await _httpClient.GetAsync(healthUrl);
            return response.IsSuccessStatusCode;
        }
        catch
        {
            return false;
        }
    }
}

/// <summary>
/// 主节点端点信息
/// </summary>
public class MasterEndpointInfo
{
    public string MasterId { get; set; } = string.Empty;
    public string Host { get; set; } = string.Empty;
    public int TcpPort { get; set; }
    public int ApiPort { get; set; }
    public int Priority { get; set; }
    public bool IsDistributed { get; set; }
}

/// <summary>
/// 节点发现响应
/// </summary>
public class NodeDiscoveryResponse
{
    public MasterNodeInfo CurrentMaster { get; set; } = null!;
    public List<MasterNodeInfo> AvailableMasters { get; set; } = new();
}

/// <summary>
/// 主节点信息
/// </summary>
public class MasterNodeInfo
{
    public string MasterId { get; set; } = string.Empty;
    public string Host { get; set; } = string.Empty;
    public int TcpPort { get; set; }
    public int ApiPort { get; set; }
    public bool IsDistributed { get; set; }
    public DateTime? LastHeartbeat { get; set; }
}

/// <summary>
/// API 响应
/// </summary>
public class ApiResponse<T>
{
    public bool Success { get; set; }
    public T? Data { get; set; }
    public string? ErrorMessage { get; set; }
    public long Timestamp { get; set; }
}
